/**
 * @file parameter_data.c
 * @brief 参数读写数据模块实现
 * @details 本文件实现了104协议的参数读写数据处理功能，包括参数特征标识、
 *          TLV数据、参数读写命令等数据类型的序列化和反序列化操作。
 *          支持完整的数据转换和验证功能。
 * 
 * @author zyb
 * @date 2025-10-18
 * @version 1.0
 * 
 * @note 所有函数都遵循104协议规范，确保严格的数据处理
 * @warning 数据转换失败时应返回相应的错误码，便于上层处理
 * 
 * @see parameter_data.h
 * @see protocol_types.h
 * @see buffer_utils.h
 * @see time_utils.h
 */

#include "../include/parameter_data.h"
#include "../../common/types/include/protocol_types.h"
#include "../../../../../common/utils/include/buffer_utils.h"
#include "../../common/utils/include/time_utils.h"
#include "../../common/error/include/error_codes.h"
#include "../../common/utils/include/validation_utils.h"
#include "../../../../../common/logs/include/logger.h"
#include <string.h>
#include <stdlib.h>

// 定义模块名称
#define LOG_MODULE_NAME "PARAMETER_DATA"

/* ==================== 参数特征标识处理函数实现 ==================== */

/**
 * @brief 参数特征标识转换为字节数组
 * @details 将参数特征标识结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param pi 参数特征标识结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_parameter_identification
 * @see validate_parameter_identification
 * @see buffer_write_u8
 */
protocol_error_t parameter_identification_to_bytes(const pi_t* pi,
                                                 u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换参数特征标识到字节数组: pi=%p, buffer=%p, buffer_size=%u", 
              pi, buffer, buffer_size);
    
    if (pi == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证参数特征标识 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证参数特征标识");
    if (!is_parameter_identification_valid(pi)) {
        LOG_ERROR(LOG_MODULE_NAME, "参数特征标识验证失败");
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "参数特征标识验证通过");
    
    /* 检查缓冲区大小 */
    if (buffer_size < 1) { /* PI(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < 1", buffer_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "缓冲区大小检查通过: %u >= 1", buffer_size);
    
    /* 写入参数特征标识 */
    u8 pi_value = *(u8*)pi;
    LOG_DEBUG(LOG_MODULE_NAME, "写入参数特征标识: 0x%02X 到缓冲区[0]", pi_value);
    buffer[0] = pi_value;
    
    *actual_length = 1;
    LOG_INFO(LOG_MODULE_NAME, "参数特征标识成功转换为字节数组，实际长度: %u", *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为参数特征标识
 * @details 将104协议规定的字节数组格式转换为参数特征标识结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param pi 参数特征标识结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳参数特征标识
 * 
 * @see parameter_identification_to_bytes
 * @see validate_parameter_identification
 * @see buffer_read_u8
 */
protocol_error_t bytes_to_parameter_identification(const u8* data, u32 length,
                                                 pi_t* pi) {
    LOG_DEBUG(LOG_MODULE_NAME, "字节数组转换为参数特征标识: data=%p, length=%u, pi=%p", data, length, pi);
    
    if (data == NULL || pi == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 1) { /* PI(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度不足: %u < 1", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 1", length);
    
    /* 读取参数特征标识 */
    *pi = *(pi_t*)&data[0];
    LOG_DEBUG(LOG_MODULE_NAME, "读取参数特征标识: 0x%02X", *(u8*)pi);
    
    /* 验证转换后的数据 */
    if (!is_parameter_identification_valid(pi)) {
        LOG_ERROR(LOG_MODULE_NAME, "参数特征标识验证失败");
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "参数特征标识验证通过");
    
    LOG_INFO(LOG_MODULE_NAME, "字节数组成功转换为参数特征标识");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证参数特征标识
 * @details 验证参数特征标识结构的完整性和有效性。
 *          检查保留位是否都为0。
 * 
 * @param pi 参数特征标识结构，不能为NULL
 * @return 验证结果
 *         - 1: 参数特征标识有效
 *         - 0: 参数特征标识无效
 * 
 * @note 验证保留位是否都为0
 * @warning 输入指针不能为NULL
 * 
 * @see is_parameter_identification_valid
 * @see pi_t
 */
int validate_parameter_identification(const pi_t* pi) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证参数特征标识: pi=%p", pi);
    
    if (pi == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    int result = is_parameter_identification_valid(pi);
    LOG_DEBUG(LOG_MODULE_NAME, "参数特征标识验证结果: %d", result);
    
    LOG_INFO(LOG_MODULE_NAME, "参数特征标识验证完成，结果: %d", result);
    return result;
}

/* ==================== TLV数据处理函数实现 ==================== */

/**
 * @brief TLV数据转换为字节数组
 * @details 将TLV数据结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param tlv TLV数据结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_tlv_data
 * @see validate_tlv_data
 * @see buffer_write_u8
 * @see buffer_write_u16
 * @see buffer_write_string
 */
protocol_error_t tlv_data_to_bytes(const tlv_data_t* tlv,
                                 u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换TLV数据到字节数组: tlv=%p, buffer=%p, buffer_size=%u", tlv, buffer, buffer_size);
    
    if (tlv == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证TLV数据 */
    if (!is_tlv_data_valid(tlv)) {
        LOG_ERROR(LOG_MODULE_NAME, "TLV数据验证失败");
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "TLV数据验证通过");
    
    /* 检查缓冲区大小 */
    u32 required_size = 1 + 2 + tlv->length; /* 类型(1字节) + 长度(2字节) + 数据 */
    if (buffer_size < required_size) {
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < %u", buffer_size, required_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "缓冲区大小检查通过: %u >= %u", buffer_size, required_size);
    
    u32 offset = 0;
    
    /* 写入类型 */
    buffer[offset] = (u8)tlv->data_type;
    offset += 1;
    
    /* 写入长度 */
    buffer_write_u16(&buffer[offset], 0, tlv->length, 0);
    offset += 2;
    
    /* 写入数据 */
    if (tlv->length > 0 && tlv->data != NULL) {
        LOG_DEBUG(LOG_MODULE_NAME, "写入TLV数据: 长度=%u, 偏移=%u", tlv->length, offset);
        memcpy(&buffer[offset], tlv->data, tlv->length);
        offset += tlv->length;
    }
    
    *actual_length = offset;
    LOG_INFO(LOG_MODULE_NAME, "TLV数据成功转换为字节数组，实际长度: %u", *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为TLV数据
 * @details 将104协议规定的字节数组格式转换为TLV数据结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param tlv TLV数据结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 *         - PROTOCOL_ERROR_MEMORY_ALLOCATION: 内存分配失败
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳TLV数据
 * 
 * @see tlv_data_to_bytes
 * @see validate_tlv_data
 * @see buffer_read_u8
 * @see buffer_read_u16
 */
protocol_error_t bytes_to_tlv_data(const u8* data, u32 length,
                                 tlv_data_t* tlv) {
    LOG_DEBUG(LOG_MODULE_NAME, "字节数组转换为TLV数据: data=%p, length=%u, tlv=%p", data, length, tlv);
    
    if (data == NULL || tlv == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 3) { /* 类型(1字节) + 长度(2字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度不足: %u < 3", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 3", length);
    
    u32 offset = 0;
    
    /* 读取类型 */
    tlv->data_type = (tlv_data_type_t)data[offset];
    offset += 1;
    
    /* 读取长度 */
    buffer_read_u16(&data[offset], 0, (u16*)&tlv->length, 0);
    offset += 2;
    
    /* 检查剩余数据长度 */
    if (length - offset < tlv->length) {
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    /* 分配内存并读取数据 */
    if (tlv->length > 0) {
        tlv->data = (u8*)malloc(tlv->length);
        if (tlv->data == NULL) {
            return PROTOCOL_ERROR_MEMORY_ALLOCATION;
        }
        memcpy(tlv->data, &data[offset], tlv->length);
        offset += tlv->length;
    } else {
        tlv->data = NULL;
    }
    
    /* 验证转换后的数据 */
    if (!is_tlv_data_valid(tlv)) {
        if (tlv->data != NULL) {
            free(tlv->data);
            tlv->data = NULL;
        }
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "字节数组成功转换为TLV数据");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证TLV数据
 * @details 验证TLV数据结构的完整性和有效性。
 *          检查类型、长度和数据的有效性。
 * 
 * @param tlv TLV数据结构，不能为NULL
 * @return 验证结果
 *         - 1: TLV数据有效
 *         - 0: TLV数据无效
 * 
 * @note 验证类型、长度和数据的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_tlv_data_type_valid
 * @see is_tlv_data_length_valid
 * @see tlv_data_t
 */
int validate_tlv_data(const tlv_data_t* tlv) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证TLV数据: tlv=%p", tlv);
    
    if (tlv == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    int result = (is_tlv_data_type_valid(tlv->data_type) && 
                  is_tlv_data_length_valid(tlv->length));
    
    LOG_DEBUG(LOG_MODULE_NAME, "TLV数据验证结果: %d (类型: %d, 长度: %u)", result, tlv->data_type, tlv->length);
    
    LOG_INFO(LOG_MODULE_NAME, "TLV数据验证完成，结果: %d", result);
    return result;
}

/* ==================== 参数读写命令处理函数实现 ==================== */

/**
 * @brief 参数读写命令转换为字节数组
 * @details 将参数读写命令结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param command 参数读写命令结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_parameter_command
 * @see validate_parameter_command
 * @see buffer_write_u24
 * @see buffer_write_u8
 * @see tlv_data_to_bytes
 */
protocol_error_t parameter_command_to_bytes(const parameter_data_t* command,
                                           u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换参数读写命令到字节数组: command=%p, buffer=%p, buffer_size=%u", 
              command, buffer, buffer_size);
    
    if (command == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证参数读写命令 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证信息对象地址: %u", command->info_address);
    if (!is_info_address_valid(command->info_address)) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的信息对象地址: %u", command->info_address);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_parameter_command_valid(command)) {
        LOG_ERROR(LOG_MODULE_NAME, "参数读写命令验证失败");
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "参数读写命令验证通过");
    
    /* 检查缓冲区大小 */
    u32 required_size = 3 + 1 + 1; /* 地址(3字节) + PI(1字节) + TLV数据 */
    if (command->tlv_data.length > 0) {
        required_size += 1 + 2 + command->tlv_data.length; /* 类型(1字节) + 长度(2字节) + 数据 */
    }
    LOG_DEBUG(LOG_MODULE_NAME, "计算所需缓冲区大小: %u", required_size);
    
    if (buffer_size < required_size) {
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < %u", buffer_size, required_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "缓冲区大小检查通过: %u >= %u", buffer_size, required_size);
    
    u32 offset = 0;
    
    /* 写入信息对象地址 */
    buffer_write_u32(&buffer[offset], 0, command->info_address, 0);
    offset += 3;
    
    /* 写入参数特征标识 */
    buffer[offset] = *(u8*)&command->parameter_identification;
    offset += 1;
    
    /* 写入TLV数据 */
    if (command->tlv_data.length > 0) {
        u32 tlv_length;
        protocol_error_t result = tlv_data_to_bytes(&command->tlv_data, &buffer[offset], 
                                                   buffer_size - offset, &tlv_length);
        if (result != PROTOCOL_SUCCESS) {
            return result;
        }
        offset += tlv_length;
    }
    
    *actual_length = offset;
    LOG_INFO(LOG_MODULE_NAME, "参数读写命令成功转换为字节数组，实际长度: %u", *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为参数读写命令
 * @details 将104协议规定的字节数组格式转换为参数读写命令结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param command 参数读写命令结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳参数读写命令
 * 
 * @see parameter_command_to_bytes
 * @see validate_parameter_command
 * @see buffer_read_u24
 * @see buffer_read_u8
 * @see bytes_to_tlv_data
 */
protocol_error_t bytes_to_parameter_command(const u8* data, u32 length,
                                            parameter_data_t* command) {
    LOG_DEBUG(LOG_MODULE_NAME, "字节数组转换为参数读写命令: data=%p, length=%u, command=%p", data, length, command);
    
    if (data == NULL || command == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 4) { /* 地址(3字节) + PI(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度不足: %u < 4", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 4", length);
    
    u32 offset = 0;
    
    /* 读取信息对象地址 */
    buffer_read_u32(&data[offset], 0, (u32*)&command->info_address, 0);
    offset += 3;
    LOG_DEBUG(LOG_MODULE_NAME, "读取信息对象地址: %u, 偏移: %u", command->info_address, offset);
    
    /* 读取参数特征标识 */
    command->parameter_identification = *(pi_t*)&data[offset];
    offset += 1;
    LOG_DEBUG(LOG_MODULE_NAME, "读取参数特征标识: 0x%02X, 偏移: %u", *(u8*)&command->parameter_identification, offset);
    
    /* 读取TLV数据 */
    if (length > offset) {
        LOG_DEBUG(LOG_MODULE_NAME, "读取TLV数据: 剩余长度=%u", length - offset);
        protocol_error_t result = bytes_to_tlv_data(&data[offset], length - offset, &command->tlv_data);
        if (result != PROTOCOL_SUCCESS) {
            LOG_ERROR(LOG_MODULE_NAME, "TLV数据转换失败: %d", result);
            return result;
        }
    } else {
        /* 没有TLV数据 */
        LOG_DEBUG(LOG_MODULE_NAME, "没有TLV数据，设置默认值");
        command->tlv_data.data_type = TLV_TYPE_BOOLEAN;
        command->tlv_data.length = 0;
        command->tlv_data.data = NULL;
    }
    
    /* 验证转换后的数据 */
    if (!is_info_address_valid(command->info_address)) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的信息对象地址: %u", command->info_address);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_parameter_command_valid(command)) {
        LOG_ERROR(LOG_MODULE_NAME, "参数读写命令验证失败");
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "字节数组成功转换为参数读写命令");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证参数读写命令
 * @details 验证参数读写命令结构的完整性和有效性。
 *          检查地址、参数特征标识和TLV数据的有效性。
 * 
 * @param command 参数读写命令结构，不能为NULL
 * @return 验证结果
 *         - 1: 参数读写命令有效
 *         - 0: 参数读写命令无效
 * 
 * @note 验证地址、参数特征标识和TLV数据的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_parameter_identification_valid
 * @see validate_tlv_data
 * @see parameter_command_t
 */
int validate_parameter_command(const parameter_data_t* command) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证参数读写命令: command=%p", command);
    
    if (command == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    int result = (is_info_address_valid(command->info_address) && 
                  is_parameter_identification_valid(&command->parameter_identification) && 
                  validate_tlv_data(&command->tlv_data));
    
    LOG_DEBUG(LOG_MODULE_NAME, "参数读写命令验证结果: %d (地址: %u)", result, command->info_address);
    
    LOG_INFO(LOG_MODULE_NAME, "参数读写命令验证完成，结果: %d", result);
    return result;
}

/* ==================== 辅助函数实现 ==================== */

/**
 * @brief 获取参数特征标识大小
 * @details 获取参数特征标识结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 参数特征标识大小（字节）
 * 
 * @note 参数特征标识大小：1字节
 * @warning 此函数是线程安全的
 * 
 * @see get_tlv_data_size
 * @see get_parameter_command_size
 * @see pi_t
 */
u32 get_parameter_identification_size(void) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取参数特征标识大小");
    u32 size = 1; /* PI(1字节) */
    LOG_INFO(LOG_MODULE_NAME, "参数特征标识大小: %u字节", size);
    return size;
}

/**
 * @brief 获取TLV数据大小
 * @details 获取TLV数据结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @param tlv TLV数据结构，不能为NULL
 * @return TLV数据大小（字节）
 * 
 * @note TLV数据大小：1字节 + 2字节 + 数据长度
 * @warning 输入指针不能为NULL
 * 
 * @see get_parameter_identification_size
 * @see get_parameter_command_size
 * @see tlv_data_t
 */
u32 get_tlv_data_size(const tlv_data_t* tlv) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取TLV数据大小: tlv=%p", tlv);
    
    if (tlv == NULL) {
        LOG_WARN(LOG_MODULE_NAME, "TLV数据指针为NULL，返回大小0");
        return 0;
    }
    
    u32 size = 1 + 2 + tlv->length; /* 类型(1字节) + 长度(2字节) + 数据 */
    LOG_INFO(LOG_MODULE_NAME, "TLV数据大小: %u字节 (类型: %d, 长度: %u)", size, tlv->data_type, tlv->length);
    return size;
}

/**
 * @brief 获取参数读写命令大小
 * @details 获取参数读写命令结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @param command 参数读写命令结构，不能为NULL
 * @return 参数读写命令大小（字节）
 * 
 * @note 参数读写命令大小：地址(3字节) + PI(1字节) + TLV数据大小
 * @warning 输入指针不能为NULL
 * 
 * @see get_parameter_identification_size
 * @see get_tlv_data_size
 * @see parameter_command_t
 */
u32 get_parameter_command_size(const parameter_data_t* command) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取参数读写命令大小: command=%p", command);
    
    if (command == NULL) {
        LOG_WARN(LOG_MODULE_NAME, "参数读写命令指针为NULL，返回大小0");
        return 0;
    }
    
    u32 tlv_size = get_tlv_data_size(&command->tlv_data);
    u32 total_size = 3 + 1 + tlv_size; /* 地址(3字节) + PI(1字节) + TLV数据 */
    LOG_INFO(LOG_MODULE_NAME, "参数读写命令大小: %u字节 (地址: %u, TLV大小: %u)", total_size, command->info_address, tlv_size);
    return total_size;
}

/* ==================== TLV数据类型处理函数实现 ==================== */

/**
 * @brief 获取TLV数据类型名称
 * @details 根据TLV数据类型枚举值获取对应的中文名称。
 *          用于调试和日志输出。
 * 
 * @param type TLV数据类型枚举值
 * @return TLV数据类型名称字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效类型返回"未知类型"
 * 
 * @see tlv_data_type_t
 * @see get_tlv_data_type_description
 */
const char* get_tlv_data_type_name(tlv_data_type_t type) {
    switch (type) {
        case TLV_TYPE_BOOLEAN:
            return "布尔";
        case TLV_TYPE_TINY:
            return "小整形";
        case TLV_TYPE_UTINY:
            return "无符号小整形";
        case TLV_TYPE_SHORT:
            return "短整形";
        case TLV_TYPE_USHORT:
            return "无符号短整形";
        case TLV_TYPE_INT:
            return "整形";
        case TLV_TYPE_UINT:
            return "无符号整形";
        case TLV_TYPE_LONG:
            return "长整形";
        case TLV_TYPE_ULONG:
            return "无符号长整形";
        case TLV_TYPE_FLOAT:
            return "单精度浮点";
        case TLV_TYPE_DOUBLE:
            return "双精度浮点";
        case TLV_TYPE_OCTET_STRING:
            return "八位位串类型";
        case TLV_TYPE_STRING:
            return "字符串类型";
        default:
            return "未知类型";
    }
}

/**
 * @brief 获取TLV数据类型描述
 * @details 根据TLV数据类型枚举值获取对应的详细描述。
 *          用于调试和日志输出。
 * 
 * @param type TLV数据类型枚举值
 * @return TLV数据类型描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效类型返回"未知类型"
 * 
 * @see tlv_data_type_t
 * @see get_tlv_data_type_name
 */
const char* get_tlv_data_type_description(tlv_data_type_t type) {
    switch (type) {
        case TLV_TYPE_BOOLEAN:
            return "布尔类型，值为true或false";
        case TLV_TYPE_TINY:
            return "小整形类型，8位有符号整数";
        case TLV_TYPE_UTINY:
            return "无符号小整形类型，8位无符号整数";
        case TLV_TYPE_SHORT:
            return "短整形类型，16位有符号整数";
        case TLV_TYPE_USHORT:
            return "无符号短整形类型，16位无符号整数";
        case TLV_TYPE_INT:
            return "整形类型，32位有符号整数";
        case TLV_TYPE_UINT:
            return "无符号整形类型，32位无符号整数";
        case TLV_TYPE_LONG:
            return "长整形类型，64位有符号整数";
        case TLV_TYPE_ULONG:
            return "无符号长整形类型，64位无符号整数";
        case TLV_TYPE_FLOAT:
            return "单精度浮点类型，32位浮点数";
        case TLV_TYPE_DOUBLE:
            return "双精度浮点类型，64位浮点数";
        case TLV_TYPE_OCTET_STRING:
            return "八位位串类型，二进制数据";
        case TLV_TYPE_STRING:
            return "字符串类型，文本数据";
        default:
            return "未知类型";
    }
}

/* ==================== 参数读写验证函数实现 ==================== */

/**
 * @brief 验证参数特征标识
 * @details 验证参数特征标识是否在有效范围内。
 *          检查保留位是否都为0。
 * 
 * @param pi 参数特征标识
 * @return 验证结果
 *         - 1: 参数特征标识有效
 *         - 0: 参数特征标识无效
 * 
 * @note 参数特征标识只有3位有效，其他位必须为0
 * @warning 保留位必须为0
 * 
 * @see is_tlv_data_type_valid
 * @see is_tlv_data_length_valid
 * @see pi_t
 */
int is_parameter_identification_valid(const pi_t* pi) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证参数特征标识: pi=%p", pi);
    
    if (pi == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    /* 参数特征标识只有3位有效，其他位必须为0 */
    int result = (pi->res == 0);
    LOG_DEBUG(LOG_MODULE_NAME, "参数特征标识验证结果: %d (res=%d)", result, pi->res);
    
    LOG_INFO(LOG_MODULE_NAME, "参数特征标识验证完成，结果: %d", result);
    return result;
}

/**
 * @brief 验证TLV数据类型
 * @details 验证TLV数据类型是否在有效范围内。
 *          TLV数据类型范围：1-45
 * 
 * @param type TLV数据类型
 * @return 验证结果
 *         - 1: TLV数据类型有效
 *         - 0: TLV数据类型无效
 * 
 * @note TLV数据类型范围：1-45
 * @warning TLV数据类型不能为0
 * 
 * @see is_parameter_identification_valid
 * @see is_tlv_data_length_valid
 * @see tlv_data_type_t
 */
int is_tlv_data_type_valid(tlv_data_type_t type) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证TLV数据类型: %d", type);
    
    int result = (type >= TLV_TYPE_BOOLEAN && type <= TLV_TYPE_STRING);
    LOG_DEBUG(LOG_MODULE_NAME, "TLV数据类型验证结果: %d (范围: %d-%d)", result, TLV_TYPE_BOOLEAN, TLV_TYPE_STRING);
    
    LOG_INFO(LOG_MODULE_NAME, "TLV数据类型验证完成，结果: %d", result);
    return result;
}

/**
 * @brief 验证TLV数据长度
 * @details 验证TLV数据长度是否在有效范围内。
 *          TLV数据长度范围：0-65535
 * 
 * @param length TLV数据长度
 * @return 验证结果
 *         - 1: TLV数据长度有效
 *         - 0: TLV数据长度无效
 * 
 * @note TLV数据长度范围：0-65535
 * @warning TLV数据长度不能为负数
 * 
 * @see is_tlv_data_type_valid
 * @see is_parameter_identification_valid
 */
int is_tlv_data_length_valid(u16 length) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证TLV数据长度: %u", length);
    
    int result = 1; // u16类型总是有效的
    LOG_DEBUG(LOG_MODULE_NAME, "TLV数据长度验证结果: %d (最大长度: 65535)", result);
    
    LOG_INFO(LOG_MODULE_NAME, "TLV数据长度验证完成，结果: %d", result);
    return result;
}

/**
 * @brief 验证参数读写命令
 * @details 验证参数读写命令是否在有效范围内。
 *          检查地址、参数特征标识和TLV数据的有效性。
 * 
 * @param command 参数读写命令
 * @return 验证结果
 *         - 1: 参数读写命令有效
 *         - 0: 参数读写命令无效
 * 
 * @note 验证地址、参数特征标识和TLV数据的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_parameter_identification_valid
 * @see validate_tlv_data
 * @see parameter_command_t
 */

/* ==================== TLV数据操作函数实现 ==================== */

/**
 * @brief 销毁TLV数据
 * @details 销毁TLV数据结构，释放内存。
 *          用于清理TLV数据。
 * 
 * @param tlv TLV数据结构，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 销毁成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 销毁TLV数据结构，释放内存
 * @warning 输入指针不能为NULL
 * 
 * @see create_tlv_data
 * @see copy_tlv_data
 * @see tlv_data_t
 */
protocol_error_t destroy_tlv_data(tlv_data_t* tlv) {
    LOG_DEBUG(LOG_MODULE_NAME, "销毁TLV数据: tlv=%p", tlv);
    
    if (tlv == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    if (tlv->data != NULL) {
        LOG_DEBUG(LOG_MODULE_NAME, "释放TLV数据内存: 长度=%u", tlv->length);
        free(tlv->data);
        tlv->data = NULL;
    }
    
    tlv->data_type = TLV_TYPE_BOOLEAN;
    tlv->length = 0;
    
    LOG_INFO(LOG_MODULE_NAME, "TLV数据销毁完成");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 复制TLV数据
 * @details 复制TLV数据结构，分配内存并复制数据。
 *          用于复制TLV数据。
 * 
 * @param src 源TLV数据结构，不能为NULL
 * @param dst 目标TLV数据结构，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 复制成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_MEMORY_ALLOCATION: 内存分配失败
 * 
 * @note 复制TLV数据结构，分配内存并复制数据
 * @warning 输入指针不能为NULL
 * 
 * @see create_tlv_data
 * @see destroy_tlv_data
 * @see tlv_data_t
 */
protocol_error_t copy_tlv_data(const tlv_data_t* src, tlv_data_t* dst) {
    LOG_DEBUG(LOG_MODULE_NAME, "复制TLV数据: src=%p, dst=%p", src, dst);
    
    if (src == NULL || dst == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    dst->data_type = src->data_type;
    dst->length = src->length;
    LOG_DEBUG(LOG_MODULE_NAME, "复制TLV数据属性: 类型=%d, 长度=%u", dst->data_type, dst->length);
    
    if (src->length > 0 && src->data != NULL) {
        LOG_DEBUG(LOG_MODULE_NAME, "分配TLV数据内存: 大小=%u", src->length);
        dst->data = (u8*)malloc(src->length);
        if (dst->data == NULL) {
            LOG_ERROR(LOG_MODULE_NAME, "内存分配失败");
            return PROTOCOL_ERROR_MEMORY_ALLOCATION;
        }
        memcpy(dst->data, src->data, src->length);
        LOG_DEBUG(LOG_MODULE_NAME, "TLV数据复制完成");
    } else {
        dst->data = NULL;
        LOG_DEBUG(LOG_MODULE_NAME, "源数据为空，目标数据设置为NULL");
    }
    
    LOG_INFO(LOG_MODULE_NAME, "TLV数据复制成功");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证TLV数据
 * @details 验证TLV数据结构的完整性和有效性。
 *          检查类型、长度和数据的有效性。
 * 
 * @param tlv TLV数据结构，不能为NULL
 * @return 验证结果
 *         - 1: TLV数据有效
 *         - 0: TLV数据无效
 * 
 * @note 验证类型、长度和数据的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_tlv_data_type_valid
 * @see is_tlv_data_length_valid
 * @see tlv_data_t
 */
int is_tlv_data_valid(const tlv_data_t* tlv) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证TLV数据: tlv=%p", tlv);
    
    if (tlv == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    /* 验证数据类型 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证TLV数据类型: %d", tlv->data_type);
    if (!is_tlv_data_type_valid(tlv->data_type)) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的TLV数据类型: %d", tlv->data_type);
        return 0;
    }
    
    /* 验证数据长度 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证TLV数据长度: %u", tlv->length);
    if (!is_tlv_data_length_valid(tlv->length)) {
        LOG_ERROR(LOG_MODULE_NAME, "无效的TLV数据长度: %u", tlv->length);
        return 0;
    }
    
    /* 验证数据指针一致性 */
    if (tlv->length > 0 && tlv->data == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "TLV数据长度>0但数据指针为NULL: 长度=%u", tlv->length);
        return 0;
    }
    
    if (tlv->length == 0 && tlv->data != NULL) {
        LOG_WARN(LOG_MODULE_NAME, "TLV数据长度为0但数据指针不为NULL");
    }
    
    int result = 1;
    LOG_DEBUG(LOG_MODULE_NAME, "TLV数据验证结果: %d (类型: %d, 长度: %u)", result, tlv->data_type, tlv->length);
    
    LOG_INFO(LOG_MODULE_NAME, "TLV数据验证完成，结果: %d", result);
    return result;
}

/**
 * @brief 验证参数读写命令
 * @details 验证参数读写命令是否在有效范围内。
 *          检查地址、参数特征标识和TLV数据的有效性。
 * 
 * @param command 参数读写命令结构，不能为NULL
 * @return 验证结果
 *         - 1: 参数读写命令有效
 *         - 0: 参数读写命令无效
 * 
 * @note 验证地址、参数特征标识和TLV数据的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_parameter_identification_valid
 * @see validate_tlv_data
 * @see parameter_command_t
 */
int is_parameter_command_valid(const parameter_data_t* command) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证参数读写命令: command=%p", command);
    
    if (command == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return 0;
    }
    
    int result = (is_info_address_valid(command->info_address) && 
                  is_tlv_data_valid(&command->tlv_data));
    
    LOG_DEBUG(LOG_MODULE_NAME, "参数读写命令验证结果: %d (地址: %u)", result, command->info_address);
    
    LOG_INFO(LOG_MODULE_NAME, "参数读写命令验证完成，结果: %d", result);
    return result;
}

